package es.xpt.ysf.commons.configuration;

import java.util.List;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import es.xpt.ysf.YSFException;
import es.xpt.ysf.commons.Names;
import es.xpt.ysf.commons.configuration.model.MultiParameter;
import es.xpt.ysf.commons.configuration.model.Parameter;
import es.xpt.ysf.commons.configuration.model.ParameterValue;
import es.xpt.ysf.jaas.YSFPrincipal;
import es.xpt.ysf.logging.LogManager;
import es.xpt.ysf.utils.ServiceLocator;

public class ParametersStore {

	private YSFPrincipal principal;
	private static final String NO_DEF_VALUE = "NO_DEF_VALUE";
	
	public ParametersStore (YSFPrincipal principal) {
		this.principal = principal;
	}
			
	private void loadCache ( Cache cache ) {
		try {
			ServiceLocator sl = new ServiceLocator(principal, "");
			ConfigurationSession conf = (ConfigurationSession) sl.getLocal(Names.CONFIGURATION);
			List<ParameterValue> list = conf.getParameters();
			for ( ParameterValue pv : list ) {
				cache.put(new Element(pv.getCode(), pv.getValue()));
			}
		} catch ( YSFException e ) {
			LogManager.getLog(getClass()).error(e.getMessage(), e);
		}
	}
	
	public Object getRealValue ( Parameter<?> parameter ) {
		String s = getValue ( parameter.getParameterName() );
		if ( s!= null && !s.equals(NO_DEF_VALUE))
			return parameter.getValue(s);
		else return null;
	}
	
	public Object getRealValue ( MultiParameter parameter, String type ) {
		String s = getValue ( parameter.getParameterName(type) );
		if ( s!= null && !s.equals(NO_DEF_VALUE))
			return parameter.getValue(s);
		else return null;
	}
	
	public Object getValue( Parameter<?> parameter ) {
		String s = getValue ( parameter.getParameterName() );
		if ( s!= null && !s.equals(NO_DEF_VALUE))
			return parameter.getValue(s);
		else return parameter.getDefaultValue();
	}
	
	public Object getValue( MultiParameter parameter, String type ) {
		String s = getValue ( parameter.getParameterName(type) );
		if ( s!= null && !s.equals(NO_DEF_VALUE))
			return parameter.getValue(s);
		else return parameter.getDefaultValue(type);
	}
	
	private String getValue( String parameterName ) {
		
		Cache cache = CacheManager.getInstance().getCache("parametersCache@" + principal.getApplication());
		if ( cache!=null ) { 
			if ( cache.getSize()==0) {
				loadCache(cache);
			}
			Element e = cache.get(parameterName);
			if ( e!=null && e.getObjectValue()!=null 
					&& !((String)e.getObjectValue()).equals(NO_DEF_VALUE) ) {
				return (String)e.getObjectValue();
			} else if ( e==null || e.getObjectValue()==null ) {
				cache.put(new Element(parameterName, NO_DEF_VALUE));
			}
			return null;
		} else {
			throw new RuntimeException("parameters Cache not available");
		}
		
	}
		
}
